﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Oliving.Edge.Common.IncodeHelper;
using Oliving.Edge.Common.TimeHelper;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;

namespace Oliving.Edge.Extensions
{

    //  Asp.net Core五类过滤器：Authorization Filter、Resource Filter、Acton Filter、Exception Filter、Result Filter。优先级逐次递减。




    public class GlobalInterfaceFilter : Attribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var eHeader = context.HttpContext.Request.Headers;


            QueryString eQueryString = context.HttpContext.Request.QueryString;
            string qString = eQueryString.Value;


            AuthInterfaceDto para = GetAuthPara(qString.ToLower());

            AuthInterfaceDto paraA = GetAuthPara(eHeader);



            string msg = "";
            bool bo = AuthenticationAuthority("", para, out msg);

            if (bo) { return; }
            else
            {
                context.Result = new JsonResult("全局权限设置 => " + msg); return;
            }

        }

        /// <summary>
        /// 分析 header 中的参数 
        /// </summary>
        /// <param name="eHeader"></param>
        /// <returns></returns>
        private AuthInterfaceDto GetAuthPara(IHeaderDictionary eHeader)
        {
            if (eHeader.Keys.Contains("AppCode".ToLower()) 
                || eHeader.Keys.Contains("Sign".ToLower())
                || eHeader.Keys.Contains("TimeStamp".ToLower()))
            {
                return new AuthInterfaceDto()
                {
                    AppCode = eHeader["AppCode".ToLower()],
                    Sign = eHeader["Sign".ToLower()],
                    TimeStamp = eHeader["TimeStamp".ToLower()]
                };
            }
            return null;
        }






        /// <summary>
        /// 权限调用验证
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="para">参数对象</param>
        /// <param name="msg">返回消息</param>
        /// <returns></returns>
        public bool AuthenticationAuthority(string url, AuthInterfaceDto para, out string msg)
        {
            msg = "";
            if (para == null)
            {
                msg = "参数不完整！";
                return false;
            }

            #region 超时判断

            DateTime dtNow = TimeStampUtil.GetTime(para.TimeStamp);

            if (DateTime.Now.AddMinutes(5) > dtNow && DateTime.Now.AddMinutes(-5) < dtNow)
            {

            }
            else
            {
                msg = "请求超时！与服务器时间";
                return false;
            }
            #endregion

            #region 获取密码 secret

            string pwd = GetPassWord(para.AppCode);

            if (pwd != null && !string.IsNullOrEmpty(pwd))
            {
                string newSign = Des3Utility.Des3EncodeECBDefault(para.AppCode + pwd + para.TimeStamp);

                if (newSign != para.Sign)
                {
                    msg = "验证失败！";

                    return false;
                }

            }
            #endregion
            else
            {
                msg = "[" + para.AppCode + "]此API账号无效！";
                return false;
            }

            return true;
        }

        /// <summary>
        /// 获取项目对应的面
        /// </summary>
        /// <param name="appCode"></param>
        /// <returns></returns>
        public string GetPassWord(string appCode)
        {
            return "123456";
        }


        private AuthInterfaceDto GetAuthPara(string s)
        {
            string baseUrl = "";
            NameValueCollection nv = ParseUrl(s, out baseUrl);
            string a = nv["AppCode"];
            if (nv.AllKeys.Contains("AppCode".ToLower())
                || nv.AllKeys.Contains("Sign".ToLower())
                || nv.AllKeys.Contains("TimeStamp".ToLower()))
            {
                return new AuthInterfaceDto()
                {
                    AppCode = nv["AppCode".ToLower()],
                    Sign = nv["Sign".ToLower()],
                    TimeStamp = nv["TimeStamp".ToLower()]
                };
            }
            return null;
        }


        /// <summary>
        /// 分析url链接，返回参数集合
        /// </summary>
        /// <param name="url">url链接</param>
        /// <param name="baseUrl"></param>
        /// <returns></returns>
        public static System.Collections.Specialized.NameValueCollection ParseUrl(string url, out string baseUrl)
        {
            baseUrl = "";
            if (string.IsNullOrEmpty(url))
                return null;
            System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();

            try
            {
                int questionMarkIndex = url.IndexOf('?');

                if (questionMarkIndex == -1)
                    baseUrl = url;
                else
                    baseUrl = url.Substring(0, questionMarkIndex);
                if (questionMarkIndex == url.Length - 1)
                    return null;
                string ps = url.Substring(questionMarkIndex + 1);

                // 开始分析参数对   
                System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", System.Text.RegularExpressions.RegexOptions.Compiled);
                System.Text.RegularExpressions.MatchCollection mc = re.Matches(ps);

                foreach (System.Text.RegularExpressions.Match m in mc)
                {
                    nvc.Add(m.Result("$2").ToLower(), m.Result("$3"));
                }

            }
            catch { }
            return nvc;
        }





    }

    /// <summary>
    /// 权限参数对象
    /// </summary>
    public class AuthInterfaceDto
    {
        /// <summary>
        ///  调用方
        /// </summary>
        public string AppCode { get; set; }
        /// <summary>
        /// 加密串
        /// </summary>
        public string Sign { get; set; }
        /// <summary>
        /// 时间戳
        /// </summary>
        public string TimeStamp { get; set; }

    }

    public class InterfaceFilter : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            //如果失败，页面提示 
            context.Result = new JsonResult("MyFilter2设置，无权限访问");
        }


    }
}
